package com.yxhl.zoume.core.busticket.ui.fragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.EditText;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.yxhl.protobuf.StartCityEntry;
import com.yxhl.zoume.R;
import com.yxhl.zoume.common.ui.custom.QuickIndexBar;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.busticket.model.BusSelectCityEntity;
import com.yxhl.zoume.core.busticket.model.ObservableLetterEntity;
import com.yxhl.zoume.core.busticket.presenter.BusSearchStationPresenter;
import com.yxhl.zoume.core.busticket.presenter.StartCitiesPresenter;
import com.yxhl.zoume.core.busticket.ui.activity.BusStationsListActivity;
import com.yxhl.zoume.core.busticket.ui.adapter.BusStartStationAdapter;
import com.yxhl.zoume.core.busticket.ui.adapter.StationType;
import com.yxhl.zoume.core.busticket.ui.info.ZMScheduleType;
import com.yxhl.zoume.core.busticket.view.BusStartStationView;
import com.yxhl.zoume.core.busticket.view.SearchStationView;
import com.yxhl.zoume.di.component.busticket.BusStationComponent;
import com.yxhl.zoume.utils.CollectionUtils;
import com.yxhl.zoume.utils.alphabet.AlphabetHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnTextChanged;
import jp.wasabeef.recyclerview.animators.SlideInUpAnimator;
import rx.Subscriber;

/**
 * Created by vhawk on 16/3/20.
 */
public class BusStartStationFragment extends BaseFragment implements BusStartStationView, SearchStationView {

    public static final String TAG = "BusStartStationFragment";

    private static final int RECYCLER_VIEW_ADD_DURATION = 180;

    //widgets
    @BindView(R.id.et_special_car_start_station_search)
    EditText mSearchInputEt;

    @BindView(R.id.recycler_bus_ticket_cities)
    RecyclerView mStartStationsRecyclerView;

    @BindView(R.id.tv_center_index)
    TextView mCenterIndex;

    @BindView(R.id.qib)
    QuickIndexBar mIndexBar;


    //arguments
    @Inject
    StartCitiesPresenter mStartCitiesPresenter;
    @Inject
    BusSearchStationPresenter mStartStationSearchPresenter;

    private BusStartStationAdapter mBusStartStationAdapter;
    private BusStationComponent component;//巴士车站的component

    private MaterialDialog dialogForWaitingCities;

    private List<BusSelectCityEntity> mBusSelectCityEntityList = new ArrayList<>();
    private List<BusSelectCityEntity> mBackUpBusSelectCityEntityList = new ArrayList<>();


    public static Fragment newInstance() {
        return new BusStartStationFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

//    private void onRxBusEvent() {
//        //处理接收到的触摸字母事件
//        getSubscription().add(toSubscription(SelectLetterEvent.class,
//                new Action1<SelectLetterEvent>() {
//                    @Override
//                    public void call(SelectLetterEvent selectLetterEvent) {
//                        if (selectLetterEvent != null) {
//                            String letter = selectLetterEvent.getCurrentLetter();
//                            int indexOf = mBusSelectCityEntityList.indexOf(new BusSelectCityEntity(letter, ""));
//                            LOG.e(TAG, "onRxBusEvent indexOf=" + indexOf);
//                            if (mStartStationsRecyclerView != null) {
//                                mStartStationsRecyclerView.scrollToPosition(indexOf);
//                            }
//                        }
//                    }
//                },
//                new Action1<Throwable>() {
//                    @Override
//                    public void call(Throwable throwable) {
//                        LOG.e(TAG, "throwable=" + throwable.toString());
//                        onRxBusEvent();
//                    }
//                }
//        ));
//    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mStartCitiesPresenter.attachView(this);
        mStartStationSearchPresenter.attachView(this);
        initRecyclerView();
        queryBusStations();
        mIndexBar.setOnIndexChangeListener(new MyOnIndexChangeListener());
        return view;
    }

    private void initRecyclerView() {
        mBusStartStationAdapter = new BusStartStationAdapter(
                component.context(),
                mBusSelectCityEntityList,
                StationType.STATION_TYPE_START);

        mStartStationsRecyclerView.setLayoutManager(new LinearLayoutManager(component.context()));
        mStartStationsRecyclerView.setItemAnimator(new SlideInUpAnimator(new OvershootInterpolator(1f)));
        mStartStationsRecyclerView.getItemAnimator().setAddDuration(RECYCLER_VIEW_ADD_DURATION);
        mStartStationsRecyclerView.setAdapter(mBusStartStationAdapter);
    }

    @OnTextChanged(R.id.et_special_car_start_station_search)
    public void searchInputTextChange(CharSequence text) {
        int length = text.length();
        if (length <= 0) {
            mBusSelectCityEntityList.clear();
            mBusSelectCityEntityList.addAll(mBackUpBusSelectCityEntityList);
            mBusStartStationAdapter.notifyDataSetChanged();
        } else {
            mStartStationSearchPresenter.search(text.toString());
        }
    }

    /**
     * 巴士车票：城市列表查询
     */
    private void queryBusStations() {
        mStartCitiesPresenter.fetchBusStations();
    }


    @Override
    public void renderBusStationListResult(List<StartCityEntry> startCityEntryList) {
        if (!CollectionUtils.isEmpty(startCityEntryList)) {

            final Map<String, List<BusSelectCityEntity>> alphabetMap = new HashMap<>();

            AlphabetHelper.getStartAlphabetObservable(startCityEntryList)
                    .subscribe(new Subscriber<ObservableLetterEntity>() {
                        @Override
                        public void onCompleted() {
                            final List<BusSelectCityEntity> beanList = AlphabetHelper.getBusAlphabetData(alphabetMap);
                            if (beanList != null && beanList.size() > 0) {
                                mStartStationSearchPresenter.setAlphabetMap(alphabetMap);
                                mStartStationSearchPresenter.setStations(beanList);
                                //用来搜索后RecyclerView显示的数据集
                                mBackUpBusSelectCityEntityList.addAll(beanList);

                                //this is another way refresh UI in work thread ,rather than by handler/message
                                mActivity.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        //avoid consistent detected error
                                        if (mBusSelectCityEntityList != null) {
                                            int originalSize = mBusSelectCityEntityList.size();
                                            if (originalSize > 0) {
                                                mBusSelectCityEntityList.clear();
                                                mBusStartStationAdapter.notifyItemRangeRemoved(0, originalSize);
                                            }

                                            mBusSelectCityEntityList.addAll(beanList);
                                            mBusStartStationAdapter.notifyItemRangeInserted(0, beanList.size());
                                            waitingForQueryCities(false);
                                        }
                                    }
                                });
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onNext(ObservableLetterEntity observableLetterEntity) {
                            String letter = observableLetterEntity.getLetter();
                            String cityCode = observableLetterEntity.getCityCode();
                            String cityName = observableLetterEntity.getCityName();
                            List<ZMScheduleType> scheduleTypeList = observableLetterEntity.getScheduleTypeList();


                            List<BusSelectCityEntity> beanList = alphabetMap.get(letter);
                            if (beanList != null) {
                                beanList.add(new BusSelectCityEntity(cityName, cityCode));
                            } else {
                                beanList = new LinkedList<>();
                                beanList.add(new BusSelectCityEntity(letter, ""));
                                beanList.add(new BusSelectCityEntity(cityName, cityCode, scheduleTypeList));
                                alphabetMap.put(letter, beanList);
                            }

                        }
                    });

        }
    }

    @Override
    public void waitingForQueryCities(boolean isWaiting) {
        if (isWaiting) {
            dialogForWaitingCities = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_loading)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();

        } else {
            if (null != dialogForWaitingCities && dialogForWaitingCities.isShowing()) {
                dialogForWaitingCities.dismiss();
            }
        }
    }

    @Override
    public void onSearchResult(List<BusSelectCityEntity> busSelectCityEntityList) {
        if (busSelectCityEntityList != null && busSelectCityEntityList.size() > 0) {
            mBusSelectCityEntityList.clear();
            mBusSelectCityEntityList.addAll(busSelectCityEntityList);
        } else {
            mBusSelectCityEntityList.clear();
        }
        mBusStartStationAdapter.notifyDataSetChanged();
    }


    @Override
    public void onPause() {
        super.onPause();
        mStartCitiesPresenter.onPause();
        mStartStationSearchPresenter.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        mStartCitiesPresenter.onResume();
        mStartStationSearchPresenter.onResume();
    }

    @Override
    public void onDestroyView() {
        //放置 consistency detected error
        if (mBusSelectCityEntityList != null) {
            int originalSize = mBusSelectCityEntityList.size();
            if (originalSize > 0) {
                mBusSelectCityEntityList.clear();
                if (mBusStartStationAdapter != null) {
                    mBusStartStationAdapter.notifyItemRangeRemoved(0, originalSize);
                }
            }
            mBusSelectCityEntityList = null;
        }
        //防止 window leak
        if (dialogForWaitingCities != null && dialogForWaitingCities.isShowing()) {
            dialogForWaitingCities.dismiss();
        }

        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mStartCitiesPresenter.onDestroy();
        mStartStationSearchPresenter.onDestroy();
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_bus_ticket_start_city_list;
    }

    @Override
    protected void setupToolBar() {
        if (getActivity() instanceof BusStationsListActivity) {
            ((BusStationsListActivity) getActivity()).setToolbarTitle(getString(R.string.start_city_hint));
        }
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(BusStationComponent.class);
        component.inject(this);
    }

    private class MyOnIndexChangeListener implements QuickIndexBar.OnIndexChangeListener {
        @Override
        public void onIndexChange(String selectAlphabet) {
            mCenterIndex.setText(selectAlphabet);
            mCenterIndex.setVisibility(View.VISIBLE);
            int indexOf = mBusSelectCityEntityList.indexOf(new BusSelectCityEntity(selectAlphabet, ""));
            if (indexOf >= 0) {
                if (mStartStationsRecyclerView != null) {
                    mStartStationsRecyclerView.scrollToPosition(indexOf);
                }
            }
        }

        @Override
        public void onActionUp() {
            mCenterIndex.setVisibility(View.GONE);
        }
    }
}
